mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 04:43:54 +01:00
On Logout, fetch the CSRF token and then make the post logout call (#3182)
* Api call for logout * call clear cached onCompleteSessionLogout
This commit is contained in:
parent
958bbbdd81
commit
53d0d5e4a0
5 changed files with 122 additions and 45 deletions
|
|
@ -1,5 +1,12 @@
|
||||||
package fr.free.nrw.commons;
|
package fr.free.nrw.commons;
|
||||||
|
|
||||||
|
import static org.acra.ReportField.ANDROID_VERSION;
|
||||||
|
import static org.acra.ReportField.APP_VERSION_CODE;
|
||||||
|
import static org.acra.ReportField.APP_VERSION_NAME;
|
||||||
|
import static org.acra.ReportField.PHONE_MODEL;
|
||||||
|
import static org.acra.ReportField.STACK_TRACE;
|
||||||
|
import static org.acra.ReportField.USER_COMMENT;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
|
|
@ -9,27 +16,12 @@ import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||||
|
import com.facebook.imagepipeline.core.ImagePipeline;
|
||||||
import com.facebook.imagepipeline.core.ImagePipelineConfig;
|
import com.facebook.imagepipeline.core.ImagePipelineConfig;
|
||||||
import com.squareup.leakcanary.LeakCanary;
|
import com.squareup.leakcanary.LeakCanary;
|
||||||
import com.squareup.leakcanary.RefWatcher;
|
import com.squareup.leakcanary.RefWatcher;
|
||||||
|
|
||||||
import org.acra.ACRA;
|
|
||||||
import org.acra.annotation.AcraCore;
|
|
||||||
import org.acra.annotation.AcraDialog;
|
|
||||||
import org.acra.annotation.AcraMailSender;
|
|
||||||
import org.acra.data.StringFormat;
|
|
||||||
import org.wikipedia.AppAdapter;
|
|
||||||
import org.wikipedia.language.AppLanguageLookUpTable;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.auth.SessionManager;
|
import fr.free.nrw.commons.auth.SessionManager;
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
||||||
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao;
|
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao;
|
||||||
|
|
@ -48,15 +40,18 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.internal.functions.Functions;
|
import io.reactivex.internal.functions.Functions;
|
||||||
import io.reactivex.plugins.RxJavaPlugins;
|
import io.reactivex.plugins.RxJavaPlugins;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
import java.io.File;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import org.acra.ACRA;
|
||||||
|
import org.acra.annotation.AcraCore;
|
||||||
|
import org.acra.annotation.AcraDialog;
|
||||||
|
import org.acra.annotation.AcraMailSender;
|
||||||
|
import org.acra.data.StringFormat;
|
||||||
|
import org.wikipedia.AppAdapter;
|
||||||
|
import org.wikipedia.language.AppLanguageLookUpTable;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
import static org.acra.ReportField.ANDROID_VERSION;
|
|
||||||
import static org.acra.ReportField.APP_VERSION_CODE;
|
|
||||||
import static org.acra.ReportField.APP_VERSION_NAME;
|
|
||||||
import static org.acra.ReportField.PHONE_MODEL;
|
|
||||||
import static org.acra.ReportField.STACK_TRACE;
|
|
||||||
import static org.acra.ReportField.USER_COMMENT;
|
|
||||||
|
|
||||||
@AcraCore(
|
@AcraCore(
|
||||||
buildConfigClass = BuildConfig.class,
|
buildConfigClass = BuildConfig.class,
|
||||||
resReportSendSuccessToast = R.string.crash_dialog_ok_toast,
|
resReportSendSuccessToast = R.string.crash_dialog_ok_toast,
|
||||||
|
|
@ -250,6 +245,7 @@ public class CommonsApplication extends Application {
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(() -> {
|
.subscribe(() -> {
|
||||||
Timber.d("All accounts have been removed");
|
Timber.d("All accounts have been removed");
|
||||||
|
clearImageCache();
|
||||||
//TODO: fix preference manager
|
//TODO: fix preference manager
|
||||||
defaultPrefs.clearAll();
|
defaultPrefs.clearAll();
|
||||||
defaultPrefs.putBoolean("firstrun", false);
|
defaultPrefs.putBoolean("firstrun", false);
|
||||||
|
|
@ -258,6 +254,14 @@ public class CommonsApplication extends Application {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all images cache held by Fresco
|
||||||
|
*/
|
||||||
|
private void clearImageCache() {
|
||||||
|
ImagePipeline imagePipeline = Fresco.getImagePipeline();
|
||||||
|
imagePipeline.clearCaches();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all tables and re-creates them.
|
* Deletes all tables and re-creates them.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
36
app/src/main/java/fr/free/nrw/commons/auth/LogoutClient.java
Normal file
36
app/src/main/java/fr/free/nrw/commons/auth/LogoutClient.java
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
package fr.free.nrw.commons.auth;
|
||||||
|
|
||||||
|
|
||||||
|
import io.reactivex.Observable;
|
||||||
|
import java.util.Objects;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import org.wikipedia.dataclient.Service;
|
||||||
|
import org.wikipedia.dataclient.ServiceFactory;
|
||||||
|
import org.wikipedia.dataclient.WikiSite;
|
||||||
|
import org.wikipedia.dataclient.mwapi.MwPostResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for logout
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class LogoutClient {
|
||||||
|
|
||||||
|
private final Service service;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public LogoutClient(@Named("commons-wikisite")
|
||||||
|
WikiSite commonsWikiSite) {
|
||||||
|
service = ServiceFactory.get(commonsWikiSite);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the CSRF token and uses that to post the logout api call
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Observable<MwPostResponse> postLogout() {
|
||||||
|
return service.getCsrfToken().concatMap(tokenResponse -> service.postLogout(
|
||||||
|
Objects.requireNonNull(Objects.requireNonNull(tokenResponse.query()).csrfToken())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -144,15 +144,6 @@ public class SessionManager {
|
||||||
.map(a -> accountManager.removeAccount(a, null, null).getResult()))
|
.map(a -> accountManager.removeAccount(a, null, null).getResult()))
|
||||||
.doOnComplete(() -> {
|
.doOnComplete(() -> {
|
||||||
currentAccount = null;
|
currentAccount = null;
|
||||||
clearImageCache();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear all images cache held by Fresco
|
|
||||||
*/
|
|
||||||
private void clearImageCache(){
|
|
||||||
ImagePipeline imagePipeline = Fresco.getImagePipeline();
|
|
||||||
imagePipeline.clearCaches();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
||||||
* @param contribution
|
* @param contribution
|
||||||
*/
|
*/
|
||||||
private void fetchAndDisplayThumbnail(DisplayableContribution contribution) {
|
private void fetchAndDisplayThumbnail(DisplayableContribution contribution) {
|
||||||
String keyForLRUCache = getKeyForLRUCache(contribution.getContentUri());
|
String keyForLRUCache = contribution.getFilename();
|
||||||
String cacheUrl = thumbnailCache.get(keyForLRUCache);
|
String cacheUrl = thumbnailCache.get(keyForLRUCache);
|
||||||
if (!StringUtils.isBlank(cacheUrl)) {
|
if (!StringUtils.isBlank(cacheUrl)) {
|
||||||
imageView.setImageURI(cacheUrl);
|
imageView.setImageURI(cacheUrl);
|
||||||
|
|
@ -132,15 +132,6 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns image key for the LRU cache, basically the id of the image, (the content uri is the ""+/id)
|
|
||||||
* @param contentUri
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private String getKeyForLRUCache(Uri contentUri) {
|
|
||||||
return contentUri.getLastPathSegment();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
compositeDisposable.clear();
|
compositeDisposable.clear();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
package fr.free.nrw.commons.theme;
|
package fr.free.nrw.commons.theme;
|
||||||
|
|
||||||
|
import static fr.free.nrw.commons.di.NetworkingModule.NAMED_COMMONS_WIKI_SITE;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
import android.accounts.AccountManager;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
|
@ -22,6 +25,10 @@ import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.auth.LogoutClient;
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
|
@ -40,6 +47,8 @@ import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||||
import fr.free.nrw.commons.logging.CommonsLogSender;
|
import fr.free.nrw.commons.logging.CommonsLogSender;
|
||||||
import fr.free.nrw.commons.review.ReviewActivity;
|
import fr.free.nrw.commons.review.ReviewActivity;
|
||||||
import fr.free.nrw.commons.settings.SettingsActivity;
|
import fr.free.nrw.commons.settings.SettingsActivity;
|
||||||
|
import org.wikipedia.dataclient.Service;
|
||||||
|
import org.wikipedia.dataclient.WikiSite;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public abstract class NavigationBaseActivity extends BaseActivity
|
public abstract class NavigationBaseActivity extends BaseActivity
|
||||||
|
|
@ -61,6 +70,15 @@ public abstract class NavigationBaseActivity extends BaseActivity
|
||||||
|
|
||||||
private ActionBarDrawerToggle toggle;
|
private ActionBarDrawerToggle toggle;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
LogoutClient logoutClient;
|
||||||
|
|
||||||
|
|
||||||
|
private CompositeDisposable disposable = new CompositeDisposable();
|
||||||
|
private Service service;
|
||||||
|
|
||||||
|
private ProgressDialog progressDialog;
|
||||||
|
|
||||||
public void initDrawer() {
|
public void initDrawer() {
|
||||||
navigationView.setNavigationItemSelectedListener(this);
|
navigationView.setNavigationItemSelectedListener(this);
|
||||||
|
|
||||||
|
|
@ -201,9 +219,7 @@ public abstract class NavigationBaseActivity extends BaseActivity
|
||||||
.setMessage(R.string.logout_verification)
|
.setMessage(R.string.logout_verification)
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.setPositiveButton(R.string.yes, (dialog, which) -> {
|
.setPositiveButton(R.string.yes, (dialog, which) -> {
|
||||||
BaseLogoutListener logoutListener = new BaseLogoutListener();
|
handleLogout();
|
||||||
CommonsApplication app = (CommonsApplication) getApplication();
|
|
||||||
app.clearApplicationData(this, logoutListener);
|
|
||||||
})
|
})
|
||||||
.setNegativeButton(R.string.no, (dialog, which) -> dialog.cancel())
|
.setNegativeButton(R.string.no, (dialog, which) -> dialog.cancel())
|
||||||
.show();
|
.show();
|
||||||
|
|
@ -227,6 +243,36 @@ public abstract class NavigationBaseActivity extends BaseActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask the logout client to post the logout api
|
||||||
|
*/
|
||||||
|
private void handleLogout() {
|
||||||
|
if (null == progressDialog) {
|
||||||
|
progressDialog = new ProgressDialog(this);
|
||||||
|
progressDialog.setMessage(getString(R.string.please_wait));
|
||||||
|
}
|
||||||
|
|
||||||
|
progressDialog.show();
|
||||||
|
|
||||||
|
disposable.add(logoutClient.postLogout()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(mwQueryResponse -> {
|
||||||
|
BaseLogoutListener logoutListener = new BaseLogoutListener();
|
||||||
|
CommonsApplication app = (CommonsApplication) getApplication();
|
||||||
|
app.clearApplicationData(this, logoutListener);
|
||||||
|
progressDialog.cancel();
|
||||||
|
},
|
||||||
|
t -> {
|
||||||
|
progressDialog.cancel();
|
||||||
|
Toast.makeText(NavigationBaseActivity.this,
|
||||||
|
t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
|
||||||
|
Timber.e(t, "Something went wrong with post logout api: %s", t
|
||||||
|
.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
private class BaseLogoutListener implements CommonsApplication.LogoutListener {
|
private class BaseLogoutListener implements CommonsApplication.LogoutListener {
|
||||||
@Override
|
@Override
|
||||||
public void onLogoutComplete() {
|
public void onLogoutComplete() {
|
||||||
|
|
@ -294,4 +340,13 @@ public abstract class NavigationBaseActivity extends BaseActivity
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
disposable.clear();
|
||||||
|
if (progressDialog != null && progressDialog.isShowing()) {
|
||||||
|
progressDialog.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue